#include<stdio.h>
#include<stdlib.h>
typedef struct
{
    unsigned short bfType;
    unsigned int bfSize;
    unsigned short bfReserved1;
    unsigned short bfResvered2;
    unsigned int bfOffbits;
} FileHeader;
typedef struct
{
    unsigned int biSize;
    unsigned long biWidth;
    unsigned long biHeight;
    unsigned short biPlanes;
    unsigned short biBitCount;
    unsigned int bitCompression;
    unsigned int biSizeImage;
    unsigned long biXPelsPerMeter;
    unsigned long biYPelsPerMeter;
    unsigned int biClrUsed;
    unsigned int biClrImportant;
} FileInfo;
//分析32位图像，无调色板，调色板视作数据区
typedef struct
{
    unsigned char blue;
    unsigned char green;
    unsigned char red;
    unsigned char reserved;
} ColorTable;
typedef struct
{
    FileHeader header;
    FileInfo info;
    ColorTable table;
} BMP;
void readFileHeader(FILE *fp,FileHeader *header);
void readFileInfo(FILE *fp,FileInfo *header);
void readColor(FILE *fp,ColorTable *header);
void writeFileHeader(FILE *fp,FileHeader *header);
void writeFileInfo(FILE *fp,FileInfo *header);
void writeColor(FILE *fp,ColorTable *header);
int main()
{
    FILE *fp=fopen("test.bmp","rb");
    FILE *new_fp=fopen("new.bmp","wb");
    FileHeader t;
    FileInfo p;
    ColorTable c;
    readFileHeader(fp,&t);
    printf("%d\n%d\n%d\n%d\n%d\n",t.bfType,t.bfSize,t.bfReserved1,t.bfResvered2,t.bfOffbits);
    writeFileHeader(new_fp,&t);
    readFileInfo(fp,&p);
    printf("%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\n",p.biSize,p.biWidth,p.biHeight,p.biPlanes,p.biBitCount,p.bitCompression,p.biSizeImage,p.biXPelsPerMeter,p.biYPelsPerMeter,p.biClrUsed,p.biClrImportant);
    writeFileInfo(new_fp,&p);
    char *rgb=(char *)malloc(p.biSizeImage);
    fread(rgb,1,p.biSizeImage,fp);
    for(unsigned int i=0;i<p.biSizeImage;i+=4)
    {
        rgb[i]=(rgb[i]*19595+38469*rgb[i+1]+7472*rgb[i+2])>>16;
        rgb[i+1]=rgb[i+2]=rgb[i];
    }
    fwrite(rgb,1,p.biSizeImage,new_fp);
    fclose(fp);
    fclose(new_fp);
    return 0;
}
void readFileHeader(FILE *fp,FileHeader *header)
{
    fread(&(header->bfType),2,1,fp);
    fread(&(header->bfSize),4,1,fp);
    fread(&(header->bfReserved1),2,1,fp);
    fread(&(header->bfResvered2),2,1,fp);
    fread(&(header->bfOffbits),4,1,fp);
}
void readFileInfo(FILE *fp,FileInfo *header)
{
    fread(&(header->biSize),4,1,fp);
    fread(&(header->biWidth),4,1,fp);
    fread(&(header->biHeight),4,1,fp);
    fread(&(header->biPlanes),2,1,fp);
    fread(&(header->biBitCount),2,1,fp);
    fread(&(header->bitCompression),4,1,fp);
    fread(&(header->biSizeImage),4,1,fp);
    fread(&(header->biXPelsPerMeter),4,1,fp);
    fread(&(header->biYPelsPerMeter),4,1,fp);
    fread(&(header->biClrUsed),4,1,fp);
    fread(&(header->biClrImportant),4,1,fp);
}
void readColor(FILE *fp,ColorTable *header)
{
    fread(&(header->red),1,1,fp);
    fread(&(header->green),1,1,fp);
    fread(&(header->blue),1,1,fp);
    fread(&(header->reserved),1,1,fp);
}
void writeFileHeader(FILE *fp,FileHeader *header)
{
    fwrite(&(header->bfType),2,1,fp);
    fwrite(&(header->bfSize),4,1,fp);
    fwrite(&(header->bfReserved1),2,1,fp);
    fwrite(&(header->bfResvered2),2,1,fp);
    fwrite(&(header->bfOffbits),4,1,fp);
}
void writeFileInfo(FILE *fp,FileInfo *header)
{
    fwrite(&(header->biSize),4,1,fp);
    fwrite(&(header->biWidth),4,1,fp);
    fwrite(&(header->biHeight),4,1,fp);
    fwrite(&(header->biPlanes),2,1,fp);
    fwrite(&(header->biBitCount),2,1,fp);
    fwrite(&(header->bitCompression),4,1,fp);
    fwrite(&(header->biSizeImage),4,1,fp);
    fwrite(&(header->biXPelsPerMeter),4,1,fp);
    fwrite(&(header->biYPelsPerMeter),4,1,fp);
    fwrite(&(header->biClrUsed),4,1,fp);
    fwrite(&(header->biClrImportant),4,1,fp);
}
void writeColor(FILE *fp,ColorTable *header)
{
    fwrite(&(header->red),1,1,fp);
    printf("red=%d,",header->red);
    fwrite(&(header->green),1,1,fp);
    printf("green=%d,",header->green);
    fwrite(&(header->blue),1,1,fp);
    printf("blue=%d,",header->blue);
    fwrite(&(header->reserved),1,1,fp);
    printf("alpha=%d\n",header->reserved);
}